/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logic;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.Documento;
import model.Palabra;
import model.Posteo;
import model.Valoracion;
import model.Vocabulario;
import persistence.SqlConnector;

/**
 *
 * @author
 */
public class Buscador1 {

    private String consulta;
    private LinkedList<String> terminos;
    private HashMap<String, Valoracion> valoracion;
    private Vocabulario voc = null;
    private int n;//total de documentos

    public Buscador1(String consulta) {
        this.consulta = consulta;
        valoracion = new HashMap<String, Valoracion>();
        this.voc = Vocabulario.getInstance();
        System.out.println("Vocabulario tiene palabras: " + voc.getTerminos().size());
        try {
            n=getTotalDocs();
        } catch (Exception ex) {
            Logger.getLogger(Buscador1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void procesarConsulta() {
        String consultaLimpia = Utils.limpiarAcentos(consulta);
        terminos = Utils.separarPalabras(consultaLimpia);
    }

    public void setConsulta(String consulta) {
        this.consulta = consulta;
    }

    public String getConsulta() {
        return consulta;
    }

    public LinkedList<String> getTerminos() {
        return terminos;
    }

    public void setTerminos(LinkedList<String> terminos) {
        this.terminos = terminos;
    }

    public Valoracion[] buscar() throws Exception {
        procesarConsulta();
        SqlConnector connector = new SqlConnector();
        connector.connect();
        boolean debug = true;
        
        for (String termino : terminos) { //FOR POR CADA TERMINO

            Palabra palabra = voc.getPalabra(termino);
            if (palabra != null) {
                ArrayList<Posteo> posteoList = new ArrayList<Posteo>();
                try {

                    //Armar posteos (new Posteo()) de esa palabra con sus documentos.
                    Documento doc = null;
                    ResultSet result = connector.executeStatementQuery("SELECT * FROM posteos p WHERE p.idTermino = " + palabra.getId());

                    while (result.next()) {
                        ResultSet resultDoc = connector.executeStatementQuery("SELECT * FROM documento d WHERE d.id = " + result.getInt("idDoc"));
                        if (resultDoc.next()) {
                            doc = new Documento(resultDoc.getInt("id"), resultDoc.getString("nombre"), resultDoc.getString("path"), resultDoc.getInt("cantPalabras"));
                        }
                        posteoList.add(new Posteo(doc, result.getInt("tf")));
                    }

                    //Recorrer posteos armados de esa palabra e ir armando los objetos Valoracion (new Valoracion())
                    for (Posteo posteo : posteoList) {
                        Valoracion val = valoracion.put(posteo.getDocumento().getNombre(), new Valoracion(posteo.getDocumento()));
                        if (val != null) {
                            val.incrementarCantTerminosDeConsultaEnDoc(); //Revisar si con "val" afecto al mismo objeto que el anterior (en teoría si)
                        }
                        val = valoracion.get(posteo.getDocumento().getNombre());

                        val.setValoracion(val.getValoracion() + (double) (1 - ((double) palabra.getCantDoc()
                                / (double) voc.getTerminos().size()) * (double) posteo.getTf()));

                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        //Normalizar pesos - Comentado ya que no tengo los archivos en Disco y en tal caso Valoración pasará a valer "cualquier churro"

        for (Map.Entry<String, Valoracion> valor : valoracion.entrySet()) {
            System.out.println("Antes: " + valor.getValue().getValoracion());
            valor.getValue().setValoracion(valor.getValue().getValoracion() * valor.getValue().getCantTerminosDeConsultaEnDoc()
                    / valor.getValue().getDocumento().getCantPalabras()); //getLongitud() debería devolver el tamaño del archivo en disco...
            System.out.println("Despues: " + valor.getValue().getValoracion());
        }

//        Valoracion[] valoracionArray = (Valoracion[]) valoracion.values().toArray(); PORQUE NO FUNCA ASI?

        Collection<Valoracion> valoracionCollection = valoracion.values();
        Valoracion[] valoracionArray = new Valoracion[valoracionCollection.size()];
        int i = 0;
        for (Valoracion val : valoracionCollection) {
            valoracionArray[i] = val;
            i++;
        }

        Ordenador ordenador = new Ordenador(valoracionArray);
        ordenador.ordenar();

        return valoracionArray;
    }

    private int getTotalDocs() throws Exception {
        SqlConnector connector = new SqlConnector();
        connector.connect();
        ResultSet result = connector.executeStatementQuery("SELECT count(*) as n FROM documento");
        result.next();
        int n= result.getInt("n");
        System.out.println(n);
        connector.disconnect();
        return n;

    }
}
